﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ADC.Comet.Core;
using Sharp.Framework.Extensions;

namespace Sharp.Framework.Comet
{
    /// <summary>
    /// Web消息管理对象
    /// </summary>
    public class MessageManagement
    {
        /// <summary>
        /// 单例对象
        /// </summary>
        private static readonly MessageManagement ObjectInstance = new MessageManagement();


        /// <summary>
        /// 单例
        /// </summary>
        static public MessageManagement Instance
        {
            get { return ObjectInstance; }
        }
        /// <summary>
        /// 消息列表
        /// </summary>
        readonly List<Message> _messageList;
        /// <summary>
        /// 请求队列
        /// </summary>
        private readonly LinkedList<Message> _messageQueue;
        /// <summary>
        /// 消息缓存超时处理定时器
        /// </summary>
        readonly Timer _timer;
        /// <summary>
        /// 缓存消息
        /// </summary>
        public int Count {get{ return _messageList.Count;}}
        /// <summary>
        /// 检查间隔
        /// </summary>
        const int TimerPeriod = 60 * 1000;
        /// <summary>
        /// 超时时间
        /// </summary>
        const int Timeout = 20*60 * 1000;
        /// <summary>
        /// 日志对象
        /// </summary>
        protected FileLogger Log;
        /// <summary>
        /// 构造方法
        /// </summary>
        public MessageManagement( )
        {
            Log = new FileLogger();
            _messageList = new List<Message>();
            _messageQueue = new LinkedList<Message>();
            _timer = new Timer(TimerProc);
            _timer.Change(0, TimerPeriod);
        }
        /// <summary>
        /// 定时器,用于移除旧消息的消息
        /// </summary>
        /// <param name="state"></param>
        private void TimerProc(object state)
        {
            try
            {
                var timeoutNodes = new List<Message>();
                lock (_messageList)
                {
                    var now = DateTime.Now.GenerateTimeStamp();
                    var n = _messageQueue.First;
                    while (n != null)
                    {
                        var diff = (now - n.Value.Created);
                        if (diff > Timeout)
                        {
                            timeoutNodes.Add(n.Value);
                        }
                        else
                        {
                            break;
                        }
                        n = n.Next;
                    }
                    foreach (var rn in timeoutNodes)
                    {
                        _messageQueue.Remove(rn); 
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, "消息缓存超时处理服务");
            }
        }
        /// <summary>
        /// 查找消息
        /// </summary>
        /// <param name="receiver"></param>
        /// <param name="from"></param>
        /// <returns></returns>
        public List<Message> Find(int receiver, long from)
        {
            lock (_messageList)
            {
                var messages =
                    _messageList.Where(
                        m => m.Receiver == receiver && (m.Created > from)).OrderBy(m => m.Created)
                        .ToList();
                return messages;
            }
        }
        /// <summary>
        /// 添加新消息
        /// </summary>
        /// <param name="message"></param>
        public void Add(Message message)
        {
            lock (_messageList)
            {
                _messageList.Add(message);
            }
        }

        public void Remove(Message message)
        {
            lock (_messageList)
            {
                _messageList.Remove(message);
            }
        }
    }
}